package com.jydw.da.frame.config.table;

import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Properties;

/**
 * 我标准切分算法
 *
 * @author chenyj
 * @date 2023/06/26
 */
@Slf4j
public class MyStandardTableShardingAlgorithm implements StandardShardingAlgorithm<Long> {
    //yml穿透过来
    private  Properties properties = new Properties();


    private static final String SHARDING_COUNT_KEY = "sharding-count";

    private int shardingCount;

    /**
     * 精确分片
     *
     * @param availableTargetNames 有效的数据源或表的名字。这里就对应配置文件中配置的数据源信息
     * @param shardingValue        包含 逻辑表名、分片列和分片列的值。
     * @return 返回目标结果
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        //id取模
        //表前缀
        String prefix = shardingValue.getDataNodeInfo().getPrefix();
        //后缀最小长度
        int suffixMinLength = shardingValue.getDataNodeInfo().getSuffixMinLength();
        //0
        char paddingChar = shardingValue.getDataNodeInfo().getPaddingChar();
        long suffix = shardingValue.getValue() % shardingCount;
        String tableName = prefix + suffix;
        if (availableTargetNames.contains(tableName)) {
            return tableName;
        }
        throw new UnsupportedOperationException(" route " + tableName + " is not supported. please check your config");
    }

    /**
     * 范围分片
     *
     * @param availableTargetNames
     * @param rangeShardingValue   包含逻辑表名、分片列和分片列的条件范围。
     * @return 返回目标结果。可以是多个。
     */
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> rangeShardingValue) {
        //范围查找查找所有
        return availableTargetNames;
    }

    @Override
    public Properties getProps() {
        log.info("properties: {}", properties.toString());
        //对应yml中的type,这里怎么定义，那里就怎么写
        return this.properties;
    }



    @Override
    public String getType() {
        return "MY-STANDARD";
    }

    @Override
    public void init(Properties properties) {
        this.properties = properties;
        shardingCount = getShardingCount(properties);
        log.info("调用了初始化方法");
    }

    private int getShardingCount(final Properties props) {
        Preconditions.checkArgument(props.containsKey(SHARDING_COUNT_KEY), "Sharding count can not be null.");
        return Integer.parseInt(props.getProperty(SHARDING_COUNT_KEY));
    }
}
